import re
from random import randint

# A dice roller that gives you the option to cheat.  Takes dice rolls using
# standard RPG format (3d6, 2d4+12, etc).  Spaces between elements are safe.
# cheatRoll and bustedRoll are optional rolling types that mimic the houserules
# I use for character creation.

def evalRoll(dieRoll):
    modRoll = re.match('([0-9]+)\D*[dD]\D*([0-9]+)\D*([+-])\D*([0-9]+)', dieRoll)
    shortRoll = re.match('([0-9]+)\D*[dD]\D*([0-9]+)', dieRoll)
    shortMultiRoll = re.match('([0-9]+)\D*[dD]\D*([0-9]+)\D*[xX]\D*([0-9]+)', dieRoll)
    modMultiRoll = re.match('([0-9]+)\D*[dD]\D*([0-9]+)\D*([+-])\D*([0-9]+)\D*[xX]\D*([0-9]+)', dieRoll)
    modMultiRollAfter = re.match('([0-9]+)\D*[dD]\D*([0-9]+)\D*[xX]\D*([0-9]+)\D*([+-])\D*([0-9]+)', dieRoll)
    if modMultiRoll:
        return ("modMultiRoll",modMultiRoll.groups())
    if modMultiRollAfter:
        return ("modMultiRollAfter",modMultiRollAfter.groups())
    if modRoll:
        return ("modRoll",modRoll.groups())
    if shortMultiRoll:
        return ("shortMultiRoll",shortMultiRoll.groups())
    if shortRoll:
        return ("shortRoll",shortRoll.groups())
    else:
        return ("BROKEN")

def diceRoller(dieRoll,cheat=0):
    rollType = evalRoll(dieRoll)
    info = rollType[1]
    startRoll = 1 + cheat
    cheatDice = int(round(cheat/2.0))
    rolls = []
    for i in range(int(info[0]) + cheatDice):
        rolls.append(randint(1+cheat,int(info[1])))
    if cheatDice == 1:
        rolls.sort()
        junk = rolls.pop(0)
    rollTotal = sum(rolls)
    if rollType[0] == "modRoll":
        total = rollTotal + int(info[2] + info[3])
        return (total,rolls)
    if rollType[0] == "shortRoll":
        total = rollTotal
        return (total,rolls)
    if rollType[0] == "shortMultiRoll":
        total = rollTotal * int(info[2])
        return (total,rolls)
    if rollType[0] == "modMultiRoll":
        total = (rollTotal + int(info[2] + info[3])) * int(info[4])
        return (total,rolls)
    if rollType[0] == "modMultiRollAfter":
        total = (rollTotal * int(info[2])) + int(info[3] + info[4])
        return (total,rolls)
    else:
        return "broken"


if __name__ == "__main__":
    print evalRoll('3d6')[0]
    print evalRoll('3d6+3')[0]
    print evalRoll('3d6x10')[0]
    print evalRoll('3d6+3x10')[0]
    print evalRoll('3d6x10+3')[0]
    print diceRoller('3d6')
    print diceRoller('3d6+3')
    print diceRoller('3d6x10')
    print diceRoller('3d6+3x10')
    print diceRoller('3d6x10+3')
    print diceRoller('5d4',1)
    print diceRoller('5d4+8',1)
    print diceRoller('5d4x8',1)
    print diceRoller('5d4+8x8',1)
    print diceRoller('5d4x8+8',1)
    print diceRoller('7d8',2)
    print diceRoller('7d8+5',2)
    print diceRoller('7d8x12',2)
    print diceRoller('7d8+3x12',2)
    print diceRoller('7d8x12+5',2)
